import Vue from "vue";
import TMessage from "./message.vue";

/**
 *  使用基础 Vue 构造器，创建一个“子类”。参数是一个包含组件选项的对象。
    data 选项是特例，需要注意 - 在 Vue.extend() 中它必须是函数
 */
const MessageClass = Vue.extend(TMessage);

/**
 *  工厂函数 - 创建一个 Message 组件对象
 *
 * @param {string | object} data 传入提示的信息或配置
 */

let instanceList = [];

function Message(data = {}) {
  if (typeof data === "string") {
    data = {
      message: data,
    };
  }

  //  在触发close的时候，再触发Message.close
  data.onClosed = function() {
    Message.close(instance);
  };

  //  传入的data属性会与原先的data属性进行合并
  let instance = new MessageClass({
    data,
  });

  instance.$mount();
  document.body.appendChild(instance.$el);

  //  默认的偏移量为20
  let offset = 20;

  //  第0个的偏移量为20
  let offsetTop = offset;

  //  刚开始队列不存在实例，所以offsetTo为20
  instanceList.forEach((item) => {
    offsetTop += item.$el.offsetHeight + offset;
  });

  instance.$el.style.top = offsetTop + "px";

  //  管理实例的队列
  instanceList.push(instance);
}

/**
 *  让消息消失的时候, 可以向上偏移
 *
 *  获取当前instance的高度, 然后这个消失的instance后面的所有实例减去这个高度，再减去默认的偏移
 *
 *  @param {MessageClass} instance
 */
Message.close = function(instance) {
  let needToRemoveHieght = instance.$el.offsetHeight + instance.offset;

  let index = instanceList.indexOf(instance);

  instanceList = instanceList.filter((item) => item !== instance);

  //  被删除后, index的位置就是原来instance的下一个消息
  for (let i = index; i < instanceList.length; i++) {
    instanceList[i].$el.style.top =
      parseFloat(instanceList[i].$el.style.top) - needToRemoveHieght + "px";
  }
};

/**
 *
 *  每次都要表明type很麻烦, 我希望可以通过Message.success("messaeg")
 *  这种方式进行调用
 */

["success", "error", "warning", "info"].forEach((type) => {
  Message[type] = function(data) {
    if (typeof data === "string") {
      data = {
        message: data,
      };
    }
    data.type = type;
    Message(data);
  };
});

export default Message;
